package main

import (
	"errors"
	"fmt"
	"go-trans/trans"
	"go-trans/xutil"
	"io/ioutil"
	"log"
	"os"
	"regexp"
	"strings"
)

var transCount int
var allTransCount int
var allTransOkCount int
var fileChangeCount int

func main() {

	// 文件夹路径，不带最后 \
	//dirPath := `C:\Locker\project\isoftstone\vsn\temp\vsm`
	//dirPath := `E:\项目\新建文件夹\vsm-web`
	dirPath := `C:\Locker\project\isoftstone\vsn\temp\vsm-web`
	//filename := dirPath + `InitializationRunner1.java`
	// 是否开启次级目录检查
	childLevelCheck := true
	// 筛选文件正则
	fileMatchRegexp := ".js"
	// 翻译
	transFrom := trans.ZH
	transTo := trans.EN

	allFiles, err := filesMatch(dirPath, fileMatchRegexp, childLevelCheck)

	if err != nil {
		fmt.Println(err)
		panic(errors.New("read dir path fail"))
	}

	for _, filename := range allFiles {
		fileChangeCount += 1
		fmt.Println("fileChangeCount: [", fileChangeCount, "] - ", filename)
		contentChange(filename, transFrom, transTo)
	}

	fmt.Println("all trans count is [", allTransCount, "], good-trans count is [", allTransOkCount, "]")
}

// 获取指定路径下全部包路径及匹配正则的文件
func filesMatch(dirPath string, expr string, childLevelCheck bool) (files []string, err error) {
	var reg *regexp.Regexp = nil
	if expr != "" {
		//先编译正则 提高匹配效率
		reg, err = regexp.Compile(expr)
		if err != nil {
			log.Printf("err = %v", err)
			os.Exit(1)
		}
	}
	return interFileMatch(dirPath, reg, childLevelCheck)
}

func interFileMatch(dirPath string, reg *regexp.Regexp, childLevelCheck bool) (files []string, err error) {
	// 收集全目录
	var dirs []string
	dir, err := ioutil.ReadDir(dirPath)
	if err != nil {
		log.Printf("err = %v", err)
		os.Exit(1)
	}

	PathSeparator := string(os.PathSeparator)

	for _, fi := range dir {
		if fi.IsDir() {
			if !childLevelCheck {
				continue
			}
			dirs = append(dirs, dirPath+PathSeparator+fi.Name())
		} else {
			if reg != nil {
				ok := reg.MatchString(fi.Name())
				if ok {
					files = append(files, dirPath+PathSeparator+fi.Name())
				}
			} else {
				files = append(files, dirPath+PathSeparator+fi.Name())
			}
		}
	}

	// 当前目录下的全内容遍历，可能为文件或路径
	for _, childLevel := range dirs {
		temp, err := interFileMatch(childLevel, reg, childLevelCheck)
		if err != nil {
			log.Printf("err = %v", err)
			os.Exit(1)
		}
		for _, temp1 := range temp {
			files = append(files, temp1)
		}
	}

	return files, nil
}

// 文件内容替换
func contentChange(filename, transFrom, transTo string) {
	buf, err := ioutil.ReadFile(filename)
	if err != nil {
		log.Printf("contentChange fail, err = %v", err)
		return
	}

	transCount = 0
	contentChange1(&buf, transFrom, transTo)
	contentChange2(&buf, transFrom, transTo)
	contentChange3(&buf, transFrom, transTo)
	allTransCount += transCount
	fmt.Println("transCount: [", transCount, "]")

	// 回写文件
	writeFileErr := ioutil.WriteFile(filename, buf, os.ModePerm)
	if writeFileErr != nil {
		fmt.Println(writeFileErr)
	}

}

// 双斜线注释替换
func contentChange1(buf *[]byte, transFrom, transTo string) {
	regType := regexp.MustCompile(`\w*//\s*.*[^\x00-\xff]+.*`)
	regType1Replace, _ := regexp.Compile(`/\s+/`)
	content := string(*buf)
	match := regType.FindAllStringSubmatch(content, -1)

	for _, s := range match {
		res := trans.Trans(s[0], transFrom, transTo)
		transCount += 1
		if res != "" {
			allTransOkCount += 1
		}
		// 特殊情况处理
		res = regType1Replace.ReplaceAllString(res, "//")
		// 写回
		content = strings.Replace(content, s[0], res, 1)
	}
	*buf = []byte(content)
}

// 多行注释替换 /*...*/
func contentChange2(buf *[]byte, transFrom string, transTo string) {

	// TODO 全部多行注释，未区分中英文
	//regType := regexp.MustCompile(`/\*(\t|\n|\s)+.*[\x00-\xff]+.*(\t|\n|\s)+\*/?`)
	regType := regexp.MustCompile(`/\*(\t|\n|\s)[\s\S]*?\*/`)
	regType1Replace, _ := regexp.Compile(`/\s+\*`)
	regType2Replace, _ := regexp.Compile(`\*\s+/`)
	content := string(*buf)
	match := regType.FindAllStringSubmatch(content, -1)
	for _, s := range match {
		// 去掉全英文注释
		if !xutil.RegexpsContainZH(s[0]) {
			continue
		}

		// 翻译
		res := trans.Trans(s[0], transFrom, transTo)
		transCount += 1
		if res != "" {
			allTransOkCount += 1
		}
		// 特殊情况处理
		res = regType1Replace.ReplaceAllString(res, "/*")
		res = regType2Replace.ReplaceAllString(res, "*/")
		// 写回
		content = strings.Replace(content, s[0], res, 1)
	}
	*buf = []byte(content)
}

// 多行注释替换 /**...*/
func contentChange3(buf *[]byte, transFrom string, transTo string) {
	// TODO 全部多行注释，未区分中英文
	//regType := regexp.MustCompile(`/\*(\t|\n|\s)+.*[\x00-\xff]+.*(\t|\n|\s)+\*/?`)
	regType := regexp.MustCompile(`/\*\*(\t|\n|\s)[\s\S]*?\*/`)
	regType1Replace, _ := regexp.Compile(`(/\*\s+\*|/\s+\*\s+\*)`)
	regType2Replace, _ := regexp.Compile(`\*\s+/`)
	content := string(*buf)
	match := regType.FindAllStringSubmatch(content, -1)
	for _, s := range match {
		// 去掉全英文注释
		if !xutil.RegexpsContainZH(s[0]) {
			continue
		}

		// 翻译
		res := trans.Trans(s[0], transFrom, transTo)
		transCount += 1
		if res != "" {
			allTransOkCount += 1
		}
		// 特殊情况处理
		res = regType1Replace.ReplaceAllString(res, "/**")
		res = regType2Replace.ReplaceAllString(res, "*/")
		// 写回
		content = strings.Replace(content, s[0], res, 1)
	}
	*buf = []byte(content)
}
